/*(C) Copyright

    This file is part of widget Meteoclimatic. 
    Autor: Antonio Cristóbal Álvarez Abellán -> acabellan@gmail.com
    
    */

package deeloco.android.meteoclimatic.donate;

import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Currency;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

import deeloco.android.meteoclimatic.donate.net.DownloadTexto;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap.Config;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.Toast;

/**
 * Clase que permite gestionar los datos meteorológicos de una estación.
 * @author Antonio Cristóbal Álvarez Abellán
 *
 */

public class estacion{
	
	private final String tag="meteoclimatic.estacion";
	//private final String preURL="http://meteoclimatic.com/feed/rss/";
	private final String pathSD="/sdcard/meteoclimatic/";
	private DownloadTexto dt;
	
	/**
	 * ATRIBUTOS
	 */
	/**
	 * Nombre de la estación
	 */
	private String nombre; //Nombre de la estación
	/**
	 * Código de la estación
	 */
	private String codigo; //Código de la estación
	/**
	 * Estado de la estación
	 * True - Online
	 * False - Offline
	 */
	private Boolean estado=true; //online, offline
	/**
	 * Últimos dato meteorológicos disponibles 
	 */
	private datosMeteorologicos datosMeteo = new datosMeteorologicos(); //Datos meteorológicos
	/**
	 * Datos meteorológicos anteiores
	 */
	private datosMeteorologicos datosMeteoPrev=new datosMeteorologicos(); //Datos meteorológicos previos
	/**
	 * Contexto
	 */
	private Context contexto;
	/**
	 * Cadena que describe el error de conexión con la estación
	 */
	private String errorConexion;
	
	/**
	 * Cadena con la URL previa para la descarga de los RSS con los datos de las estaciones 
	 */
	private String preURL="http://meteoclimatic.net/feed/rss/";
	
	/**
	 * CONSTRUCTORES
	 */
	public estacion(Context contexto,String nombre, String codigo) {
		this.contexto=contexto;
		this.nombre = nombre;
		this.codigo = codigo;
		if (!crearFichero())
			setEstado(false);
		else
			setEstado(true);
		
		this.preURL=PreferenceManager.getDefaultSharedPreferences(contexto).getString("txt_valorUrl", "http://meteoclimatic.net")+"/feed/rss/";
	}
	
	public estacion() {
		this.nombre = "-- ------";
		this.codigo = "";
		//this.preURL=PreferenceManager.getDefaultSharedPreferences(this.contexto).getString("txt_valorUrl", "http://meteoclimatic.net")+"feed/rss/";
	}
	
	public estacion(Context contexto){
		this.contexto=contexto;
		this.nombre = "-- ------";
		this.codigo = "";
		this.preURL=PreferenceManager.getDefaultSharedPreferences(this.contexto).getString("txt_valorUrl", "http://meteoclimatic.net")+"/feed/rss/";
	}
	
	/**
	 * GETTER Y SETTER
	 */
	
	/**
	 * Asigna el contexto
	 * @param contexto
	 */
	public void setContexto(Context contexto){
		this.contexto=contexto;
	}
	
	/**
	 * Devuelve el Nombre de la estación
	 * @return string
	 */
	public String getNombre() {
		return nombre;
	}
	
	/**
	 * Asigna un nombre a la estación
	 * @param string nombre 
	 */
	public void setNombre(String nombre) {
		this.nombre = nombre;
	}
	
	/**
	 * Devuelve el código de la estación
	 * @return string
	 */
	public String getCodigo() {
		return codigo;
	}
	
	/**
	 * Asigna un código a la estación
	 * @param string codigo
	 */
	public void setCodigo(String codigo) {
		this.codigo = codigo;
		if (!crearFichero())
			setEstado(false);
	}
	
	/**
	 * Asigna la URL del valor de preferencias
	 */
	public void setURL()
	{
		this.preURL=PreferenceManager.getDefaultSharedPreferences(this.contexto).getString("txt_valorUrl", "http://meteoclimatic.net")+"/feed/rss/";
	}
	
	/**
	 * Devuelve los últimos datos meteorológicos descargados de la estación
	 * @return datosMeteorologicos
	 */
	public datosMeteorologicos getDatosMeteo() {
		return datosMeteo;
	}
	
	/**
	 * Devuelve los anteriores datos meteorológicos descargados de la estación
	 * @return datosMeteorologicos
	 */
	public datosMeteorologicos getDatosMeteoPrev(){
		return this.datosMeteoPrev;
	}
	
	/**
	 * Asigna datos meteorológicos a la estación
	 * @param datosMeteorologicos datosMeteo
	 */
	public void setDatosMeteo(datosMeteorologicos datosMeteo) {
		this.datosMeteo = datosMeteo;
	}
	
	
	/**
	 * Asigna datos meteorológicos previos a la estación
	 * @param datosMeteorologicos datosMeteo
	 */
	public void setDatosMeteoPrev(datosMeteorologicos datosMeteo) {
		this.datosMeteoPrev = datosMeteo;
	}

	
	/**
	 * Devuelve una medida meteorológica de la última medida tomada por la estación
	 * @param String medida : Medida a devolver (T, H, B, P o W)
	 * @return
	 */
	public double getMedidaPpal(String medida)
	{
		double retorno=0.0;
		
		retorno=(medida.compareTo(datosMeteorologicos.TEMPERATURA)==0)?this.datosMeteo.T:retorno;
		retorno=(medida.compareTo(datosMeteorologicos.HUMEDAD)==0)?this.datosMeteo.H:retorno;
		retorno=(medida.compareTo(datosMeteorologicos.PRESION)==0)?this.datosMeteo.B:retorno;
		retorno=(medida.compareTo(datosMeteorologicos.PRECIPITACION)==0)?this.datosMeteo.P:retorno;
		retorno=(medida.compareTo(datosMeteorologicos.VIENTO)==0)?this.datosMeteo.W:retorno;
		
		return retorno;
	}
	
	/**
	 * Devuelve una medida meteorológica de la última medida tomada por la estación, formateado en HTML.
	 * @param medida
	 * @param colorMedidas
	 * @param tema
	 * @return
	 */
	public String getMedidaPpalHTML(String medida,int colorMedidas, String tema)
	{
		double valorMedida=0.0;
		String unidadMedida="";
		String extra="";
		String color_medida="";
		String retorno;
		
		if (medida.compareTo(datosMeteorologicos.TEMPERATURA)==0)
		{
			valorMedida=this.datosMeteo.T;
			unidadMedida="°";
		}
		
		if (medida.compareTo(datosMeteorologicos.HUMEDAD)==0)
		{
			valorMedida=this.datosMeteo.H;
			unidadMedida="%";
		}
		
		if (medida.compareTo(datosMeteorologicos.PRESION)==0)
		{
			valorMedida=this.datosMeteo.B;
			unidadMedida="hPa";
		}
		
		if (medida.compareTo(datosMeteorologicos.PRECIPITACION)==0)
		{
			valorMedida=this.datosMeteo.P;
			unidadMedida="mm";
		}
		
		if (medida.compareTo(datosMeteorologicos.VIENTO)==0)
		{
			valorMedida=this.datosMeteo.W;
			unidadMedida="km/h";
			extra="<b>"+this.datosMeteo.getDirViento()+"</b>";
		}
		
		if (tema.equals("1"))
		{
			color_medida="#000000";
		}
		
		if (tema.equals("2"))
		{
			color_medida="#FFFFFF";
		}
		
		if (tema.equals("3"))
		{
			color_medida="#"+Integer.toHexString(colorMedidas).substring(2,8);
		}
		
		
		retorno="<font color='"+color_medida+"'><b>"+valorMedida+"</b><small>"+unidadMedida+"</small>"+extra+"</font>";
		
		return retorno;
	}
	
	/**
	 * Devuelve una lista de medidas meteorológicas formateadas en HTML.
	 * @param Boolean t 		: Si se muestra o no la Temperatura 
	 * @param Boolean h 		: Si se muestra o no la Humedad
	 * @param Boolean b 		: Si se muestra o no la Presion
	 * @param Boolean p 		: Si se muestra o no la Precipitación
	 * @param Boolean w 		: Si se muestra o no el viento
	 * @param Int colorMedidas 	: Color que se aplica al texto
	 * @param String tema 		: Que tema se ha elegido
	 * @param String separador	: Separador entre medidas
	 * @return String HTML
	 */
	public String getListaMedidasHTML(boolean t, boolean h,boolean b,boolean p,boolean w,int colorMedidas,String tema,String separador)
	{
		String retorno="";
		
		retorno+=(t)?getMedidaPpalHTML(datosMeteorologicos.TEMPERATURA, colorMedidas, tema)+"*":"";
		retorno+=(h)?getMedidaPpalHTML(datosMeteorologicos.HUMEDAD, colorMedidas, tema)+"*":"";
		retorno+=(b)?getMedidaPpalHTML(datosMeteorologicos.PRESION, colorMedidas, tema)+"*":"";
		retorno+=(p)?getMedidaPpalHTML(datosMeteorologicos.PRECIPITACION, colorMedidas, tema)+"*":"";
		retorno+=(w)?getMedidaPpalHTML(datosMeteorologicos.VIENTO, colorMedidas, tema)+"*":"";
		
		retorno=(String) retorno.subSequence(0, retorno.length()-4);
		
		retorno=retorno.replace("*", separador);
		
		return retorno;
	}
	
	/**
	 * Asigna un estado a la estación: Activa (online) o no (offline)
	 * @param boolena activa
	 */
	public void setEstado(boolean activa)
	{
		this.estado=activa;
	}
	
	/**
	 * Devuelve el estado de la estación
	 * @return boolean
	 */
	public boolean getEstado()
	{
		return this.estado;
	}
	
	
	/**
	 * Asigna un texto de error a la estacion
	 * @param error
	 */
	public void setError(String error)
	{
		this.errorConexion=error;
	}
	
	/**
	 * Devuelve el último error generado por la conexión con el servidor
	 * @return String
	 */
	public String getError()
	{
		return this.errorConexion;
	}


	/**
	 * MÉTODOS
	 */

	/**
	 * Constructor
	 * @param uRL
	 * @param nombreFichero
	 * @param pathSD
	 */
	private boolean crearFichero() 
	{
		boolean retorno=false;
		String path=this.pathSD+this.codigo;
		//Comprobamos si el fichero esta creado. Si es que no, se crea.
    	File f=new File(path);
    	if (!f.exists())
    	{
    		//El fichero no existe, hay que crearlo
    		try
    		{
    			boolean dir = new File(this.pathSD).mkdir(); //Creamos el directorio
    			retorno=true;
    		}
    		catch (Exception e)
    		{ //Error al crear el directorio o el fichero
    			Log.e(tag,"Error al crear el directorio: " + e.getMessage());
    		}
    	}
    	else
    	{
    		retorno=true;
    	}
    	return retorno;
	}
	
	
	
	/**
	 * Comprueba si existe un directorio y sino lo crea
	 * @param String dir directorio a crear
	 * @return boolean
	 */
	private boolean crearDirectorio(String dir)
	{
		File f= new File(dir);
		boolean retorno=false;
		if (!f.exists())
		{
    		//El fichero no existe, hay que crearlo
    		try
    		{
    			f.mkdir();
    			retorno=true;
    		}
    		catch (Exception e)
    		{ //Error al crear el directorio o el fichero
    			Log.e(tag,"Error al crear el directorio: " + e.getMessage());
    		}
		}
		else
		{
			retorno=true;
		}
		return retorno;
	}
	
	/**
	 * Captura los datos meteorológicos del fichero que se ha descargado.
	 * El fichero debe estar en la carpeta meteoclimatic que esta en la SD
	 * El nombre del fichero será el código de la estación
	 * @return
	 * Retorna 'true' si se ha capturado todos los datos y 'false' si no se ha podido capturar los datos.
	 */
	public boolean descargarCapturarDatos()
	{
		
		//Abrir el fichero con nombre this.nombre;
		boolean retorno=false;
		this.estado=false;
		
		if (this.codigo!=null)
        {
            if (descargarDatos())
            {
            	//Si la descarga es correcta
            	//Ahora hay que analizar el fichero descargado para obtener los datos meteorológicos
            	obtenerDatos od=new obtenerDatos();
            	datosMeteorologicos datosMeteo=null;
            	datosMeteo=od.getDatosMeteo(pathSD+this.codigo);
            	if (datosMeteo.activa)
            	{
            		//Los datos se han capturado correctamente
            		this.datosMeteoPrev=this.datosMeteo;
                	this.datosMeteo=datosMeteo;
                	this.estado=true;
                	retorno=true;
            	}
            	else
            	{
            		//Los datos no se han capturado correctamente
            		this.estado=false;
            	}
            }
            else
            {
            	//Error en la descarga
            	this.estado=false;
            }
        }
        else
        {
        	Toast.makeText(contexto,"codigo=null",Toast.LENGTH_LONG).show();
        }	
		return retorno; 

	}
	
	/**
	 * Descarga los datos meteorológicos de meteoclimatic y almacena el RSS en la tarjeta SD.
	 * @return
	 * <true> si la descarga ha sido correcta y <false> si se ha producido algún fallo.
	 */
	public boolean descargarDatos()
	{
//        descargar_fichero downFile=new descargar_fichero(this.contexto,preURL, this.codigo, pathSD);
//        return downFile.download();

		try
		{
			String urlRSSDatosEstacion=this.preURL+this.codigo;
			dt=new DownloadTexto(urlRSSDatosEstacion,contexto);
			dt.setTimeOutConnection(3000);
			dt.setTimeOutRead(3000);
			return dt.guardarDatosSD(this.pathSD+this.codigo);
		}
		catch (Exception e)
		{
			Log.e(tag,dt.getError());
			this.errorConexion=dt.getError();
			return false;
		}
       
	}
	
	/**
	 * Captura los datos meteorológicos del fichero RSS que se encuentra en la tarjeta SD
	 * @return
	 * <true> si la captura ha sido correcta y <false> si se ha producido algún fallo, como la no existencia del fichero.
	 */
	public boolean capturarDatos()
	{
		boolean retorno=true;
		//Comprobamos que la clase tiene código
		if (this.codigo!=null)
        {
			//Comprobamos si el fichero esta creado. Si es que no, se crea.
			String path=this.pathSD+this.codigo;
	    	File f=new File(path);
	    	if (f.exists())
	    	{
	    		//El fichero existe, cargamos los valores del mismo
            	//Analizar el fichero para obtener los datos meteorológicos
            	obtenerDatos od=new obtenerDatos();
            	datosMeteorologicos datosMeteo=null;
            	datosMeteo=od.getDatosMeteo(pathSD+this.codigo);
            	this.datosMeteo=datosMeteo;
	    		
	    	}
        }
		return retorno; 
	}

	/**
	 * Retorna el bitmap del icono que representa el estado del cielo
	 * @return
	 * Bitmap del icono
	 */
	public Bitmap getIcono()
	{
		Bitmap retorno=null;
		String nombreIcono			= this.datosMeteo.estadoCielo;
		String iconosPreferencias	= PreferenceManager.getDefaultSharedPreferences(this.contexto).getString("iconos", "urlIconosMeteoclimatic");
		String[] arrayIconos 		= this.contexto.getResources().getStringArray(R.array.urlIconos);
		String urlIconos			= arrayIconos[Integer.parseInt(iconosPreferencias)]; 
		Log.d("ICONO", urlIconos);
		
		String directorioIcono=pathSD+"/"+Integer.parseInt(iconosPreferencias);
		//Directorio
		if (!this.crearDirectorio(directorioIcono))
		{
			retorno=BitmapFactory.decodeResource(this.contexto.getResources(), R.drawable.icon);
			return retorno;
		}
		
		
		//String pathNombre=pathSD+"/"+Integer.parseInt(iconosPreferencias)+"/"+nombreIcono+".png";
		String pathNombre=directorioIcono+"/"+nombreIcono+".png";
    	File f=new File(pathNombre);
    	if(f.exists())
    	{
    		//Existe el fichero, devolvemos el bitmap del SD
	       BitmapFactory.Options options = new BitmapFactory.Options();
	       options.inSampleSize = 1;
	       try
	       {
	    	   Bitmap retorno2 = BitmapFactory.decodeFile(pathNombre, options).copy(Config.ARGB_8888, true);
	    	   retorno = Bitmap.createScaledBitmap(retorno2, 100, 100, false);
	       }
	       catch (Exception e)
	       {
	    	   retorno=BitmapFactory.decodeResource(contexto.getResources(), R.drawable.icon);
	       }
    	}
    	else
    	{
    		//No existe el fichero, lo descargamos a la SD, para que este disponible para la próxima vez
    	    int resId = this.contexto.getResources().getIdentifier(urlIconos, "string",this.contexto.getPackageName());
    		String URLIcono = this.contexto.getString(resId);
    		descargar_fichero downloadFile=new descargar_fichero(this.contexto,URLIcono , nombreIcono+".png", pathSD);
    		if (downloadFile.download())
    		{
    			//La descarga se ha llevado a cabo
		       BitmapFactory.Options options = new BitmapFactory.Options();
		       options.inSampleSize = 1;
		       Bitmap retorno2 = BitmapFactory.decodeFile(pathNombre, options).copy(Config.ARGB_8888, true);
	    	   retorno = Bitmap.createScaledBitmap(retorno2, 100, 100, false);
//		       retorno = BitmapFactory.decodeFile(pathNombre, options);     			
    		}
    		else
    		{
    			//Error en la descargar, pasarle el icono de meteoclimatic
    			retorno=BitmapFactory.decodeResource(this.contexto.getResources(), R.drawable.icon);
    		}

    	}
		return retorno;
		
	}
	
	/**
	 * Calcula el incremento de la lluvia entre los datos meteorológicos actuales y los previos
	 * @return Double incremento de la lluvia
	 */
	public double incrementoLluvia()
	{	
		double numero=this.datosMeteo.P-this.datosMeteoPrev.P;
		int decimales=2;
		return Math.round(numero*Math.pow(10,decimales))/Math.pow(10,decimales);
	}

	/**
	 * Devuelve el nombre de la provincia a la que pertence la estación
	 * @param mayuscula
	 * @return
	 */
	public String getProvincia(boolean mayuscula)
	{
		Resources res = contexto.getResources();
		String codProvincia=this.codigo.substring(0,7);
		String[] codProvinciasEsp = res.getStringArray(R.array.codProvinciasEspaña);
		String[] proviciasEsp = res.getStringArray(R.array.provinciasEspaña);
		for (int i = 0; i < codProvinciasEsp.length; i++) 
		{
			String provincia = codProvinciasEsp[i];
			if (provincia.equals(codProvincia)) 
				return (mayuscula)?proviciasEsp[i].toUpperCase():proviciasEsp[i];
		}
		return "";
	}
	
	/**
	 * Retorna el nombre de la estación eliminando la provincia, que suele aparecer en la cadena del nombre de la 
	 * estación.
	 * @return
	 */
	public String getNombreSinProvincia()
	{
		String nombre=this.nombre;
		return nombre.replaceAll("[(].*[)]", "");
	}

	/**
	 * Calcula la diferencia de Presión entre dos medidas consecutivas
	 * @return
	 * 		double diferencia
	 */
	public double diferenciaPresion()
	{
		double numero=Math.abs(this.datosMeteo.B-this.datosMeteoPrev.B);
		int decimales=2;
		return Math.round(numero*Math.pow(10,decimales))/Math.pow(10,decimales);
	}
	
	public String getFechaLocal()
	{
		
		
		String inputText = datosMeteo.fecha+" "+datosMeteo.hora;
        SimpleDateFormat inputFormat = new SimpleDateFormat ("dd-MM-yyyy HH:mm", Locale.getDefault());
        inputFormat.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));

        SimpleDateFormat outputFormat = new SimpleDateFormat("'<strong>'HH:mm'</strong> <small>'dd LLL'</small>'");
        // Adjust locale and zone appropriately
        
        String outputText;
        try
        {
        	Date date = inputFormat.parse(inputText);
        	outputText = outputFormat.format(date);
        }
        catch (Exception e)
    	{
        	outputText="S/D";
    	}
        
        
        return outputText;
		
		
		
//		DateFormat format=SimpleDateFormat.getTimeInstance(SimpleDateFormat.SHORT,Locale.getDefault());
//		String fechaEstacion="";
//    	Date d=null;
//    	SimpleDateFormat par = new SimpleDateFormat("dd-MM-yyyy HH:mm");  
//    	par.setTimeZone(TimeZone.getTimeZone("GMT"));
//    	try
//    	{
//    		d= par.parse(datosMeteo.fecha+" "+datosMeteo.hora);
//    		fechaEstacion=format.format(d);
//    		//Log.d(tag,"d="+d.toLocaleString()+"hora local ->"+format.format(d)+"-> hora UTC ->"+ee.getDatosMeteo().fecha+" "+ee.getDatosMeteo().hora);
//    	}
//    	catch (Exception e)
//    	{
//    		//Log.d(tag,"Error fecha: "+e.getMessage());
//    		fechaEstacion="S/D";
//    	}
//    	
//    	return fechaEstacion;
	}
	
	
	public String getDiaActualizacion()
	{
		String[] separar = datosMeteo.fecha.split("-");
		return separar[0]; // this will contain "Fruit"
	}
	
	public String getMesActualizacion()
	{
		String[] separar = datosMeteo.fecha.split("-");
		return separar[1]; // this will contain "Fruit"
	}
	
	public String getAnoActualizacion()
	{
		String[] separar = datosMeteo.fecha.split("-");
		return separar[2]; // this will contain "Fruit"
	}
	
	public String getFechaActualizacion()
	{
		return datosMeteo.fecha;
	}
	
	public String getHoraActualizacion()
	{
		return datosMeteo.hora;
	}
}
